*-----------------------------------------------------------
* Title      :Snake
* Written by :William Citrone
* Date       :03/02/2015
* Description:The first Assignment for EN0618, Advanced Games Systems Architecture
*-----------------------------------------------------------

START   ORG    $1000                 ; first instruction of program

GAMEINIT
*set the games speed
        MOVE.L  #15,SPEED
        
*turn the keyboard echo off
	    MOVE.B  #0,D1
	    MOVE.B  #12,D0
	    TRAP    #15
	
        LEA     PELLETGET,A1         
        MOVE    #0,D1          
        MOVE    #74,D0
        TRAP    #15
        
        LEA     BEEP,A1         
        MOVE    #1,D1          
        MOVE    #74,D0
        TRAP    #15

        LEA     CHEER,A1         
        MOVE    #2,D1          
        MOVE    #74,D0
        TRAP    #15
        
        LEA     BOO,A1
        MOVE    #3,D1
        MOVE    #74,D0
        TRAP    #15

RESTART
*to clear the screen when restarting the game
        MOVE.L		#$FF00,D1	
		MOVE.L		#11,D0
		TRAP		#15

GAMEMENU       
*Menu loop
        MOVE.L  #$00000000,D1
        MOVE.B  #81,D0
        TRAP    #15
        CLR.L   D1
        MOVE.W  #$150E,D1
        MOVE.B  #11,D0
        TRAP    #15
        
        LEA     WELCOMEMSG1,A1
        MOVE.B  #14,D0
        TRAP    #15
        
        MOVE.W  #$1E0F,D1
        MOVE.B  #11,D0
        TRAP    #15
        
        LEA     WELCOMEMSG2,A1
        MOVE.B  #14,D0
        TRAP    #15

        MOVE.B  #$42,D1
        MOVE.L  #19,D0
        TRAP    #15
        CMP.L   #$FF,D1
        BNE     GAMEMENU
        
GAMESETUP
*Clear the screen
        MOVE.L		#$FF00,D1	
		MOVE.L		#11,D0
		TRAP		#15
		
*Setup the main screen		

        MOVE.L  #$00999900,D1               ;setting the colour of the border
        MOVE.B  #80,D0                      
        TRAP    #15
        MOVE.L  #10,D1                      ;the width of the border
        MOVE.B  #93,D0
        TRAP    #15
    

*Drawing the border round the screen
        MOVE.W  #0,D1   ;From 0,0 to 0,360
        MOVE.W  #0,D2
        MOVE.W  #0,D3
        MOVE.W  #460,D4
        MOVE.B  #84,D0
        TRAP    #15
    
        MOVE.W  #640,D1 ;from wherever the endpoint currently id to 640,360
        MOVE.W  #460,D2
        MOVE.B  #85,D0
        TRAP    #15
    
        MOVE.W  #640,D1 ;and again to 640,0
        MOVE.W  #0,D2
        MOVE.B  #85,D0
        TRAP    #15
    
        MOVE.W  #0,D1 ;and finally back to 0,0
        MOVE.W  #0,D2
        MOVE    #85,D0
        TRAP    #15
    
*Draw a Grey Background
    
        MOVE.L  #$00B0B0B0,D1
        MOVE.B  #81,D0
        TRAP    #15
        MOVE.L  #15,D1
        MOVE.W  #15,D2
        MOVE.B  #89,D0
        TRAP    #15
        
*Set the pen's filler and outline colour.        
        MOVE.L  #$008A0829,D1
	    MOVE.B	#80,D0
	    TRAP	#15
	    MOVE.L	#$0008088A,D1
	    MOVE.B	#81,D0
	    TRAP	#15
	    
*Bring the pen back down to one pixel
	    MOVE.W	#1,D1
	    MOVE.B	#93,D0
	    TRAP	#15 
        
*filling the snakes memory with coordinates that are not on the screen
	    CLR.B	D0
	    MOVE.B	#200,D0
	    LEA 	SMIDDLE,A0
FILL
	    MOVE.W	#700,(A0)+
	    SUB.B	#1,D0
	    BNE	    FILL
	    MOVE.B	#0,SIZE	Set the snakes initial size using the state at the bottom
	    
*Place the starting point into the beginning of the middle places
	    LEA 	SMIDDLE,A0
	    MOVE.W	#5,(A0)+
	    MOVE.W	#5,(A0)
        
*Put the head of the snake into memory
	    LEA	    SFRONTEND,A0
	    MOVE.W	#5,(A0)+
	    MOVE.W	#5,(A0)
	    LEA 	SFRONTEND,A0	Reload the starting point into memory
	    BSR	    DRAWSQUARE      Call the drawing of the snakes head
	    
*Find the first pellet
	    BSR     NEWPELLET
	    MOVE.L  #50,TIMETILLPELLET
	    MOVE.L  #1,PELLETTYPE
	    MOVE.L  #0,PELLETSEQUENCE
	    
*Start movement
        MOVE.W  #0,D6
        MOVE.W  #10,D7
        
*set the initial size and score
        MOVE.L  #1,CURRENTSIZE
        MOVE.L  #0,CURRENTSCORE
        
       
*Main Game Loop
GAMELOOP   
        MOVE.B  #8,D0
        TRAP    #15
        MOVE.B  D1,D2

        MOVE.B  #23,D0
        MOVE.L  SPEED,D1
        TRAP    #15
        
        MOVE.L  #8,D0
        TRAP    #15
        SUB.L   D2,D1
        CMP.L   SPEED,D1
        	   
        BLT     GAMELOOP
        
*if enough time has passed
	    
	    BSR     DRAWSCORE
	    
	    CMP.L   #0,TIMETILLPELLET
	    BNE     NONEWPELLET
       
        
TIMENEWPELLET
        MOVE    #1,D1
        MOVE    #75,D0
        TRAP    #15
        
        MOVE.L  #$00B0B0B0,D1
	    MOVE.B	#80,D0
	    TRAP	#15
	    MOVE.L  #$00B0B0B0,D1
	    MOVE.B	#81,D0
	    TRAP	#15
	    
	    LEA     PELLET,A0
	    BRA     REMOVEPELLET
        
NEWPELLETSET   
        BSR     PELLETPUSH
             
        MOVE.L  #50,TIMETILLPELLET
        
        BRA     REPLACEPELLET
    
        
NONEWPELLET	    
        SUB.L   #1,TIMETILLPELLET
        
        MOVE.B  #8,D0
        TRAP    #15
        MOVE.L  D1,D5
        
*Copy the last position of the head into memory
        LEA     SOLDFRONT,A0
        LEA     SMIDDLE,A1
        CLR.L   D4
        MOVE.B  SIZE,D4
        SUB.B   #4,D4
        ADDA.L  D4,A1
        MOVE.W  (A1)+,(A0)+
        MOVE.W  (A1),(A0)
        
*put the middle squares into memory
        LEA     SMIDDLE,A0
        LEA     SMIDDLE,A1
        ADDA.L  #400,A0
        ADDA.L  #396,A1
        CLR.L   D4
        MOVE.L  #198,D4
        
*move the squares back one
COPY
        MOVE.W  -(A1),-(A0)
        SUB.B   #1,D4
        BNE     COPY
        
*knock the current front of the snake into the middle memory
        LEA     SMIDDLE,A0
        LEA     SFRONTEND,A1
        MOVE.W  (A1)+,(A0)+
        MOVE.W  (A1),(A0)

*keypress check
        CLR.L   D1
        MOVE.B  #7,D0
        TRAP    #15
        TST.L   D1
        BEQ     MOVEMENT
 
        MOVE.B  #$25,D1
        MOVE.L  #19,D0
        TRAP    #15
        CMP.L   #$FF,D1
        BEQ     LEFT
        
        MOVE.B  #$26,D1
        MOVE.L  #19,D0
        TRAP    #15
        CMP.L   #$FF,D1
        BEQ     UP
        
        MOVE.B  #$27,D1
        MOVE.L  #19,D0
        TRAP    #15
        CMP.L   #$FF,D1
        BEQ     RIGHT
        
        MOVE.B  #$28,D1
        MOVE.L  #19,D0
        TRAP    #15
        CMP.L   #$FF,D1
        BEQ     DOWN
        
        MOVE.B  #$46,D1
        MOVE.L  #19,D0
        TRAP    #15
        CMP.L   #$FF,D1
        BEQ     RESTART
        
*move the snake by the amount in the movement memory
MOVEMENT
        LEA     SFRONTEND,A0
        ADD.W   D6,(A0)+
        ADD.W   D7,(A0)
        
*check to see if the snakes hit a wall
        LEA     SFRONTEND,A0
        CMP.W   #5,(A0)
        BLT     WALL_END
        CMP.W   #625,(A0)+
        BHI     WALL_END
        CMP.W   #5,(A0)
        BLT     WALL_END
        CMP.W   #445,(A0)
        BHI     WALL_END
        
*check to see if the snake has hit itself
        CLR.L   D4
        MOVE.B  SIZE,D4
HAS_HIT
        CMP     #0,D4
        BLE     EATCHECK
        SUB.L   #4,D4
        LEA     SFRONTEND,A0
        LEA     SMIDDLE,A1
        ADDA.L  D4,A1
        CMP.W   (A1)+,(A0)+
        BNE     HAS_HIT
       
        CMP.W   (A1)+,(A0)+
        BNE     HAS_HIT
        
        BRA     SELF_END
        
*check if a pellet has been eaten
EATCHECK
        LEA     SFRONTEND,A0
        LEA     PELLET,A1
        CMP.W   (A0)+,(A1)+
        BNE     DRAWSNAKE
        
        CMP.W   (A0)+,(A1)+
        BNE     DRAWSNAKE
        
        IF.L #1 <eq> PELLETTYPE THEN
                ADD.L   #5,CURRENTSCORE
        ENDI
        
        IF.L    #2 <EQ> PELLETTYPE THEN
                ADD.L   #10,CURRENTSCORE
        ENDI
        
        IF.L    #3 <EQ> PELLETTYPE THEN
                ADD.L   #20,CURRENTSCORE
        ENDI
        
        BSR     PELLETPUSH
        BSR     NEWPELLET
        
        CMP.B   #199,SIZE
        BHI     DRAWSNAKE
        
        ADD.L   #1,CURRENTSIZE
        
        CMP.L   #50,CURRENTSIZE
        BEQ     GAMEWON
        
        MOVE    #0,D1
        MOVE    #75,D0
        TRAP    #15
        
        MOVE.L  #50,TIMETILLPELLET
        
        ADD.B   #4,SIZE
     
*draw the snake   
DRAWSNAKE
	    CMP.L   #1,CURRENTSIZE
	    BNE     LARGESNAKE	
        
SMALLSNAKE
        MOVE.L  #$0008088A,D1
	    MOVE.B	#80,D0
	    TRAP	#15
	    MOVE.L	#$008A0829,D1
	    MOVE.B	#81,D0
	    TRAP	#15
	    
	    LEA     SFRONTEND,A0
	    BSR     DRAWSQUARE
	    
	    MOVE.L  #$00B0B0B0,D1
	    MOVE.B	#80,D0
	    TRAP	#15
	    MOVE.L	#$00B0B0B0,D1
	    MOVE.B	#81,D0
	    TRAP	#15
	    
	    LEA     SMIDDLE,A0
	    BSR     DRAWSQUARE	   
	    
	    BRA     GAMELOOP

LARGESNAKE
        MOVE.L  #$0008088A,D1
	    MOVE.B	#80,D0
	    TRAP	#15
	    MOVE.L	#$008A0829,D1
	    MOVE.B	#81,D0
	    TRAP	#15
	    
	    LEA     SFRONTEND,A0
	    BSR     DRAWSQUARE
	    
	    MOVE.L  #$008A0829,D1
	    MOVE.B	#80,D0
	    TRAP	#15
	    MOVE.L	#$0008088A,D1
	    MOVE.B	#81,D0
	    TRAP	#15
	    
	    LEA     SMIDDLE,A0
	    BSR     DRAWSQUARE

	    MOVE.L  #$00B0B0B0,D1
	    MOVE.B	#80,D0
	    TRAP	#15
	    MOVE.L  #$00B0B0B0,D1
	    MOVE.B	#81,D0
	    TRAP	#15
	    
	    LEA     SOLDFRONT,A0
	    BSR     DRAWSQUARE
	   
	    
	    BRA     GAMELOOP
	   
*chooses the pellet type to use
PELLETPUSH
        CMP.L   #8,PELLETSEQUENCE
        BLS     PELLETPUSH2
        MOVE.L  #0,PELLETSEQUENCE

PELLETPUSH2

        ADDI.L  #1,PELLETSEQUENCE
        
        CMP.L   #1,PELLETSEQUENCE
        BEQ     SETPELLET1
        CMP.L   #2,PELLETSEQUENCE
        BEQ     SETPELLET1
        
        CMP.L   #3,PELLETSEQUENCE
        BEQ     SETPELLET2
        
        CMP.L   #4,PELLETSEQUENCE
        BEQ     SETPELLET1
        CMP.L   #5,PELLETSEQUENCE
        BEQ     SETPELLET1        
        
        CMP.L   #6,PELLETSEQUENCE
        BEQ     SETPELLET2  
      
        CMP.L   #7,PELLETSEQUENCE
        BEQ     SETPELLET3

SETPELLET1
        MOVE.L  #1,PELLETTYPE
        RTS
        
SETPELLET2
        MOVE.L  #2,PELLETTYPE
        RTS

SETPELLET3   
        MOVE.L  #3,PELLETTYPE
        MOVE.L  #0,PELLETSEQUENCE
        RTS     
	    
*displays a message upon hitting a wall
WALL_END
        MOVE.L  #$00000000,D1
        MOVE.B  #81,D0
        TRAP    #15
        CLR.L   D1
        MOVE.W  #$1E0E,D1
        MOVE.B  #11,D0
        TRAP    #15
        
        LEA     WALLHITTERMSG,A1
        MOVE.B  #14,D0
        TRAP    #15
        
        MOVE    #3,D1
        MOVE    #75,D0
        TRAP    #15
        BRA     ENDGAME
        
*displays a message upon hitting yourself
SELF_END
        MOVE.L  #$00000000,D1
        MOVE.B  #81,D0
        TRAP    #15
        CLR.L   D1
        MOVE.W  #$1E0E,D1
        MOVE.B  #11,D0
        TRAP    #15
        
        LEA     SELFHITTERMSG,A1
        MOVE.B  #14,D0
        TRAP    #15
        
        MOVE    #3,D1
        MOVE    #75,D0
        TRAP    #15
        
        BRA     ENDGAME
       
*displays a message upon winning the game 
GAMEWON
        BSR     DRAWSCORE

        MOVE.L  #$00000000,D1
        MOVE.B  #81,D0
        TRAP    #15
        CLR.L   D1
        MOVE.W  #$1E0E,D1
        MOVE.B  #11,D0
        TRAP    #15
        
        LEA     AWINNERISYOUMSG,A1
        MOVE.B  #14,D0
        TRAP    #15
        
        MOVE.W  #$1E0F,D1
        MOVE.B  #11,D0
        TRAP    #15
        
        LEA     CONGRATSMSG,A1
        MOVE.B  #14,D0
        TRAP    #15
        
        MOVE    #2,D1
        MOVE    #75,D0
        TRAP    #15
        
        MOVE.B  #23,D0
        MOVE.L  #100,D1
        TRAP    #15
        
        BRA     ENDGAME
        
ENDGAME
        
        MOVE.B  #$46,D1
        MOVE.L  #19,D0
        TRAP    #15
        CMP.L   #$FF,D1
        BEQ     RESTART
        BRA     ENDGAME
        
LEFT
        MOVE.W  #-10,D6
        MOVE.W  #0,D7
        BRA     MOVEMENT

RIGHT
        MOVE.W  #10,D6
        MOVE.W  #0,D7
        BRA     MOVEMENT

UP
        MOVE.W  #0,D6
        MOVE.W  #-10,D7
        BRA     MOVEMENT

DOWN
        MOVE.W  #0,D6
        MOVE.W  #10,D7
        BRA     MOVEMENT

NEWPELLET
        CLR.L   D1
        CLR.L   D2
        CLR.L   D3

*x-coordinate
        MOVE.B  #8,D0
        TRAP    #15
        AND.L   #$FFFF,D1
        DIVU    #62,D1
        SWAP    D1
        MOVE.W  D1,D2
        MULU    #10,D2
        ADD.W   #5,D2
        
*y-coordinate
        MOVE.B  #8,D0
        TRAP    #15
        AND.L   #$FFFF,D1
        DIVU    #44,D1
        SWAP    D1
        MOVE.W  D1,D3
        MULU    #10,D3
        ADD.W   #5,D3
   
        LEA     PELLET,A2
        MOVE.W  D2,(A2)+
        MOVE.W  D3,(A2)+
        
        CMP.L   #1,PELLETTYPE
        BEQ     NEWPELLET1
        CMP.L   #2,PELLETTYPE
        BEQ     NEWPELLET2
        CMP.L   #3,PELLETTYPE
        BEQ     NEWPELLET3
        
NEWPELLET1
        MOVE.L	#$00FE2E2E,d1
	    MOVE.B	#80,d0
	    TRAP	#15
	    MOVE.L	#$00000FF0,d1
	    MOVE.B	#81,d0
	    TRAP	#15
	    LEA     PELLET,A0
	    BSR     DRAWSQUARE
	    RTS	    

NEWPELLET2
        MOVE.L	#$00FE2E2E,d1
	    MOVE.B	#80,d0
	    TRAP	#15
	    MOVE.L	#$0000F0F0,d1
	    MOVE.B	#81,d0
	    TRAP	#15
	    LEA     PELLET,A0
	    BSR     DRAWSQUARE
	    RTS 

NEWPELLET3
        MOVE.L	#$00FE2E2E,d1
	    MOVE.B	#80,d0
	    TRAP	#15
	    MOVE.L	#$000FF000,d1
	    MOVE.B	#81,d0
	    TRAP	#15
	    LEA     PELLET,A0
	    BSR     DRAWSQUARE
	    RTS	 

	    
DRAWSQUARE
        CLR.L   D1
        CLR.L   D2
        CLR.L   D3
        CLR.L   D4
        MOVE.W  (A0)+, D1
        MOVE.W  (A0),D2
        MOVE.W  D1,D3 
        ADD.W   #10,D3
        MOVE.W  D2,D4
        ADD.W   #10,D4
        MOVE.B  #87,D0
        TRAP    #15
        RTS
        
*The replace functions are identicle to the new functions, but with a specified return, as 
*RTS returns an error when applied        
REPLACEPELLET
        CLR.L   D1
        CLR.L   D2
        CLR.L   D3
      
*x-coordinate
        MOVE.B  #8,D0
        TRAP    #15
        AND.L   #$FFFF,D1
        DIVU    #62,D1
        SWAP    D1
        MOVE.W  D1,D2
        MULU    #10,D2
        ADD.W   #5,D2
        
*y-coordinate
        MOVE.B  #8,D0
        TRAP    #15
        AND.L   #$FFFF,D1
        DIVU    #44,D1
        SWAP    D1
        MOVE.W  D1,D3
        MULU    #10,D3
        ADD.W   #5,D3
   
        LEA     PELLET,A2
        MOVE.W  D2,(A2)+
        MOVE.W  D3,(A2)+
        
        CMP.L   #1,PELLETTYPE
        BEQ     REPPELLET1
        CMP.L   #2,PELLETTYPE
        BEQ     REPPELLET2
        CMP.L   #3,PELLETTYPE
        BEQ     REPPELLET3
        
REPPELLET1
        MOVE.L	#$00FE2E2E,d1
	    MOVE.B	#80,d0
	    TRAP	#15
	    MOVE.L	#$00000FF0,d1
	    MOVE.B	#81,d0
	    TRAP	#15
	    LEA     PELLET,A0
	    BSR     DRAWSQUARE
	    BRA     NONEWPELLET	    

REPPELLET2
        MOVE.L	#$00FE2E2E,d1
	    MOVE.B	#80,d0
	    TRAP	#15
	    MOVE.L	#$0000F0F0,d1
	    MOVE.B	#81,d0
	    TRAP	#15
	    LEA     PELLET,A0
	    BSR     DRAWSQUARE
	    BRA     NONEWPELLET	 

REPPELLET3
        MOVE.L	#$00FE2E2E,d1
	    MOVE.B	#80,d0
	    TRAP	#15
	    MOVE.L	#$000FF000,d1
	    MOVE.B	#81,d0
	    TRAP	#15
	    LEA     PELLET,A0
	    BSR     DRAWSQUARE
	    BRA     NONEWPELLET	 

*DrawSquare with a specified return        
REMOVEPELLET
        CLR.L   D1
        CLR.L   D2
        CLR.L   D3
        CLR.L   D4
        MOVE.W  (A0)+, D1
        MOVE.W  (A0),D2
        MOVE.W  D1,D3 
        ADD.W   #10,D3
        MOVE.W  D2,D4
        ADD.W   #10,D4
        MOVE.B  #87,D0
        TRAP    #15
        BRA     NEWPELLETSET

DRAWSCORE
        MOVE.L  #$00000000,D1
        MOVE.B  #81,D0
        TRAP    #15
        
		MOVE.L		#11,D0			
		MOVE.L		#0,D1			
		LSL.L		#8,D1
		ADD.L		#31,D1			
		TRAP		#15
        
        LEA     SIZEMSG,A1 
        MOVE.L  CURRENTSIZE,D1
        MOVE.B  #17,D0
        TRAP    #15
        
*        MOVE.L		#11,D0			
*		MOVE.L		#20,D1			
*		LSL.L		#8,D1
*		ADD.L		#31,D1			
*		TRAP		#15
*		
*		LEA     NEXTPELLETMSG,A1 
*        MOVE.L  PELLETSEQUENCE,D1
*        MOVE.B  #17,D0
*        TRAP    #15
        
        MOVE.L		#11,D0			
		MOVE.L		#68,D1			
		LSL.L		#8,D1
		ADD.L		#31,D1			
		TRAP		#15
		
		LEA     SCOREMSG,A1 
        MOVE.L  CURRENTSCORE,D1
        MOVE.B  #17,D0
        TRAP    #15

        RTS       

    SIMHALT             ; halt simulator

SFRONTEND       DS.W    2
SOLDFRONT       DS.W    2
SMIDDLE         DS.L    100

PELLET          DS.W    2
TIMETILLPELLET  DS.L    1
PELLETTYPE      DS.L    1
PELLETSEQUENCE  DS.L    1

SIZE            DS.B    1
CURRENTSIZE     DS.L    1
CURRENTSCORE    DS.L    1

SPEED           DS.L    1

WELCOMEMSG1     DC.B    'Welcome to Snake: By William Citrone',0
WELCOMEMSG2     DC.B    'Press B to Begin.',0

WALLHITTERMSG   DC.B    'You',$60,'ve Hit A Wall!',0    
SELFHITTERMSG   DC.B	'You',$60,'ve Hit Yourself!',0

AWINNERISYOUMSG DC.B    'You',$60,'ve Won!',0
CONGRATSMSG     DC.B    'Congratulations!',0

SIZEMSG         DC.B    'Current Size: ',0
NEXTPELLETMSG   DC.B    'Next Pellet: ',0
SCOREMSG        DC.B    'Score: ',0

PELLETGET       DC.B    'ping.wav',0
BEEP            DC.B    'beep.wav',0
CHEER           DC.B    'cheer.wav',0
BOO             DC.B    'boo.wav',0

                END    START        ; last line of source









*~Font name~Courier New~
*~Font size~10~
*~Tab type~1~
*~Tab size~4~
